package edu.usc.csci578.algorithm;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.List;

import edu.usc.csci578.manager.AlgorithmManager;
import edu.usc.csci578.model.Cluster;
import edu.usc.csci578.model.ClusterEdge;

public class DependencyMeshAlgorithm extends AbstracAlgorithm
{
	public String NAME="DependencyMesheAlgorithm";
	public String DESCRIPTION="Detect the dependency mesh architecture smell in software architecture. Mesheded dependency smell happens when two component depends on a same component, and then there is a dependency relationship between them.";
	
	public DependencyMeshAlgorithm()
	{
		AlgorithmManager.getInstance().registerAlgorithm(this);
	}
		
	public SolutionSet execute(OutputStream stream) throws Exception
	{
		SolutionSet sols = new SolutionSet();
		PrintWriter out = new PrintWriter(stream);
		
		out.println("Dependency mesh Detec Algorithm Started");
		int count = 0;
		
		for(Cluster cluster:mm.getAllClusters())
		{
			List<ClusterEdge> edgeIn = cluster.getEdgesIn();
			if(edgeIn.size()>1)
			{
				for(ClusterEdge edge1: edgeIn)
					for(ClusterEdge edge2: edgeIn)
					{
						if(edge1==edge2)
							continue;
						Cluster clu1 = edge1.getSrc();
						Cluster clu2 = edge2.getSrc();
						for(ClusterEdge edgeTmp : clu1.getEdgesOut())
							if(edgeTmp.getTgt()==clu2)
							{
								Solution sol = new Solution();
								sol.add(clu1);
								sol.add(clu2);
								sol.add(cluster);
								out.println("Dependency mesh Found: "+cluster.getName()+" "+clu1.getName()+" "+clu2.getName());
								count++;
								break;
							}
					}
			}
		}
		out.println("Dependency Mesh Total Found: "+count);
		out.println("Dependency mesh Detec Algorithm Stopped");
		out.flush();
		return sols;
	}

	@Override
	public String getDescription()
	{
		return this.DESCRIPTION;
	}
	@Override
	public String getName()
	{
		return this.NAME;
	}	
	
}
